當我們在處理比較敏感的資料,像是與帳戶或與金錢相關的事,通常會有安全性的考量,這時候設定私有變數的概念就被引進程式的設計裡。
當某個變數被設定為私有,其實實現了物件導向中的核心概念:封裝性,外部程式碼無法直接訪問或修改它,必須透過特定的方式或介面,這樣可以確保數據的完整性和安全性,避免不必要的外部干擾和意外修改,更進一步,也可以透過只允許特定方法訪問和修改數據,來實現對訪問權限的控制;同時對程式碼的管理提供了優點,比如說封避免命名衝突等。
而私有變數的概念被實體化之後,其實就是唯讀和唯寫特性。
在javascript中,要實現唯讀或唯寫,可以使用getter & setter。
在物件或class裡的方法,前面加上關鍵字get
或set
就可以轉成getter或setter,雖然是方法,但使用方式就像是一般的屬性,像下面的例子:
class PerosnCl {
constructor(firstName, lastName, bityhYear, password) {
this.firstName = firstName;
this.lastName = lastName;
this.bityhYear = bityhYear;
this.password = password;
}
get fullName() {
return `${this.firstName} ${this.lastName}`;
}
set resetPassword(reset) {
if (reset) {
this.password = reset;
}
}
}
//建立instance
const john = new PerosnCl("John", "Cooper", 2000, "1234");
console.log(john.fullName); //John Cooper
對於使用者來說,fullName像是
一個屬性,而且這個屬性只能讓使用者獲得fullName
的訊息,而不能重新指定fullName
,就像是唯讀一般:
john.fullName = "John Smith";
在嚴格模式下會報錯。
使用者可使用resetPasword這個虛擬屬性
來重設密碼,因為實際上這個看起來像是屬性的東西其實是寫成setter的方法,我們可以設新的密碼,但卻沒辦法讀取我們剛剛重設的密碼。
ohn.resetPassword = "1111";
console.log(john); //看一下password確實被改了
console.log(john.resetPassword);
//但使用者透過這個接口只能設定而無法讀取
除非我們另外設定了讀取密碼的途徑(一個getter)給使用者,所以使用者必須使用特定的接口才能讀取敏感資料。
//寫在PersonCl裡
get readPassword() {
return this.password;
}
//我們不讓使用者知道密碼存在哪個屬性,
//而是讓史用者只能透過readPassword讀密碼內容,進而實現存取的控制
console.log(john.readPassword); //1111
第一次看getter & setter的時候,其實搞錯了所謂唯讀和唯寫的對象,像是文中透過fullName來實現唯讀,我一直想成是firstName和lastName會變唯讀,所以一直沒讀通。其實應該是fullName是個唯讀屬性才對(Property getters and setters把它視為accessor property)
下篇文會繼續討論getter & setter的應用:資料驗證和歷程記錄。